<html>
<head>
    <meta charset="utf-8"/>
<meta name="description" content=""/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>进阶：电池热补丁（Battery Hotpatch）之路 | 神楽小白(GZ小白)</title>
<link rel="shortcut icon" href="https://gzxiaobai.github.io/favicon.ico?v=1589593333430">
<link href="https://cdn.bootcss.com/font-awesome/5.11.2/css/all.css" rel="stylesheet">
<link rel="stylesheet" href="https://gzxiaobai.github.io/styles/main.css">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
      integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">

<script src="https://cdn.bootcss.com/highlight.js/9.15.10/highlight.min.js"></script>
<script src="https://cdn.bootcss.com/highlight.js/9.15.10/languages/dockerfile.min.js"></script>
<script src="https://cdn.bootcss.com/highlight.js/9.15.10/languages/dart.min.js"></script>
<script src="https://cdn.bootcss.com/highlight.js/9.15.10/languages/go.min.js"></script>
<script src="https://cdn.bootcss.com/moment.js/2.23.0/moment.min.js"></script>
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js"
        integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n"
        crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"
        integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo"
        crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"
        integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6"
        crossorigin="anonymous"></script>

<!-- DEMO JS -->
<!--<script src="media/scripts/index.js"></script>-->



    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.10.0/katex.min.css">
</head>
<body>
<div class="main gt-bg-theme-color-first">
    <nav class="navbar navbar-expand-lg">
    <div class="navbar-brand">
        <img class="user-avatar" src="/images/avatar.png" alt="头像">
        <div class="site-name gt-c-content-color-first">
            神楽小白(GZ小白)
        </div>
    </div>
    <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent"
            aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
        <i class="fas fa-bars gt-c-content-color-first" style="font-size: 18px"></i>
    </button>
    <div class="collapse navbar-collapse" id="navbarSupportedContent">
        <div class="navbar-nav mr-auto" style="text-align: center">
            
                <div class="nav-item">
                    
                        <a href="/" class="menu gt-a-link">
                            首页
                        </a>
                    
                </div>
            
                <div class="nav-item">
                    
                        <a href="/archives" class="menu gt-a-link">
                            归档
                        </a>
                    
                </div>
            
                <div class="nav-item">
                    
                        <a href="/tags" class="menu gt-a-link">
                            标签
                        </a>
                    
                </div>
            
                <div class="nav-item">
                    
                        <a href="/post/about" class="menu gt-a-link">
                            关于
                        </a>
                    
                </div>
            
        </div>
    </div>
</nav>
    <div class="post-container">
        <div class="post-detail gt-bg-theme-color-second">
            <article class="gt-post-content">
                <h2 class="post-title">
                    进阶：电池热补丁（Battery Hotpatch）之路
                </h2>
                <div class="post-info">
                    <time class="post-time gt-c-content-color-first">
                        · 2020-04-09 ·
                    </time>
                    
                        <a href="https://gzxiaobai.github.io/tag/2GXCvP3tq/" class="post-tags">
                            # 黑苹果
                        </a>
                    
                </div>
                <div class="post-content">
                    <h1 id="前言">前言</h1>
<p>在有了OpenCore的引导后，已经<strong>不在推荐使用DSDT</strong>了，况且，现在也是主要推广<strong>热补丁（HotPatch）</strong>，热补丁具有比DSDT更好的<strong>灵活性</strong>，于是便开始写这篇文章了。</p>
<h1 id="准备步骤">准备步骤</h1>
<p>首先，我们需要下载我提供的电池热补丁的样本（SSDT-BATT.dsl)。同时，我还准备了联想X260的电池热补丁作为例子。<br>
链接如下：<a href="https://pan.baidu.com/s/1E85uJJGzq5EXUpcTTE-CDQ">百度云</a>  <strong>密码:fn1v</strong><br>
然后，准备你的DSDT或者SSDT（存储有EC缓冲区的，Embedded Controller Buffer）</p>
<p>需要工具：<code>Hackintool，Maciasl，科学计算器（Mac自带）</code></p>
<p>要求：最好有一定的电池的基础知识，详细看见我之前写的<a href="https://gzxiaobai.github.io/post/wei-xiao-bai-she-ji-de-dian-chi-jiao-cheng-dsdt/">电池DSDT的教程</a></p>
<h1 id="初步动作">初步动作</h1>
<p>打开热补丁样本，我们来进行一些修改。（按照我自己的习惯来的）</p>
<figure data-type="image" tabindex="1"><img src="http://fp1.fghrsh.net/2020/04/09/e65fd584f0449f65f06dcab8da3027bc.png" alt="e65fd584f0449f65f06dcab8da3027bc.png" loading="lazy"></figure>
<p>我们要修改的有三处：<br>
1.DefinitionBlock的修改，将这里的<strong>ACDT</strong>改为自己<strong>DSDT开头DefinitionBlock里的第三项</strong><br>
2.DefinitionBlock的修改，将最后的数值也改成自己DSDT里的<br>
3.External引用路径里的EC路径，改成自己DSDT里的实际路径</p>
<figure data-type="image" tabindex="2"><img src="http://fp1.fghrsh.net/2020/04/09/9bc4f9b7ac2ad30173bf11d795d7898c.png" alt="9bc4f9b7ac2ad30173bf11d795d7898c.png" loading="lazy"></figure>
<p>这里我们有一处要修改：<br>
1.Scope路径下，改为自己DSDT里的实际路径</p>
<h1 id="16位和32位的处理">16位和32位的处理</h1>
<p>这里的处理，其实与DSDT里的差不多。<br>
我们先将Field复制到SSDT里<br>
<img src="http://fp1.fghrsh.net/2020/04/09/e15fd60ebcd7ceb6a922c9b7148a0c83.png" alt="e15fd60ebcd7ceb6a922c9b7148a0c83.png" loading="lazy"></p>
<p><img src="http://fp1.fghrsh.net/2020/04/09/dbd31d6f597da35e49aa1a5edeab9af1.png" alt="dbd31d6f597da35e49aa1a5edeab9af1.png" loading="lazy"><br>
像我这样复制下来，里面到内容不复制。<br>
<em><strong>注意⚠️：你不难发现，我这里有许多的Field，那是因为X260的DSDT里，就是像这样的分散的Field。因此，当你制作电池热补丁时，搜索EmbeddedControllerBuffer找到Field后，记得同时搜索Field的名称，比如，ECOR，看看有没有分散在其它地方的</strong></em></p>
<p>复制过来后，我们需要将Field进行<strong>改名</strong>，比如，ECOR，我改为了ECOX，这样就不会与原ACPI里的发生冲突。</p>
<p>热补丁与DSDT的拆分不同，我们直接将需要拆分的，拆好放到SSDT中，我们创建的Field下。</p>
<pre><code class="language-swift">        OperationRegion (ECOX, EmbeddedControl, Zero, 0x0100)
        Field (ECOX, ByteAcc, NoLock, Preserve)
        {
            Offset (0xA0), 
            RCB0,   8, 
            RCB1,   8, 
            FCB0,   8, 
            FCB1,   8, 
            Offset (0xA8), 
            ACB0,   8, 
            ACB1,   8, 
            VOB0,   8, 
            VOB1,   8
        }

        Field (ECOX, ByteAcc, NoLock, Preserve)
        {
            Offset (0xA0), 
            BMB0,   8, 
            BMB1,   8
        }

        Field (ECOX, ByteAcc, NoLock, Preserve)
        {
            Offset (0xA0), 
            DCB0,   8, 
            DCB1,   8, 
            DVB0,   8, 
            DVB1,   8, 
            Offset (0xAA), 
            SNB0,   8, 
            SNB1,   8
        }

        Field (ECOX, ByteAcc, NoLock, Preserve)
        {
            Offset (0xA0), 
            CHB0,   8, 
            CHB1,   8, 
            CHB2,   8, 
            CHB3,   8
        }
</code></pre>
<p>最后的结果就如上所示，正确拆分，正确计算偏移量。（这些都包含在我DSDT的教程中）</p>
<p>接着我们在DSDT中搜索需要被拆分的字节，找到所在的Method，记下路径，然后在SSDT里，添加这个路径。<br>
比如我们，发现GBIF这个Method里面有需要拆分的自己，观察所得，GBIF所在的路径为：</p>
<p><code>_SB.PCI0.LPC.EC</code></p>
<p>那么我们就在SSDT中加上这个Scope：</p>
<pre><code class="language-swift">    Scope (\_SB.PCI0.LPC.EC)
    {
    }
</code></pre>
<p>然后，我们将GBIF这一整个Method复制到这个路径下，在对字节进行拆分。（以此类推，其它Method也是这么处理）</p>
<pre><code class="language-swift">        Method (GBIF, 3, NotSerialized)
        {
            If (_OSI (&quot;Darwin&quot;))
            {
                Acquire (BATM, 0xFFFF)
                If (Arg2)
                {
                    Or (Arg0, One, HIID)
                    Store (B1B2 (BMB0, BMB1), Local7)
                    ShiftRight (Local7, 0x0F, Local7)
                    XOr (Local7, One, Index (Arg1, Zero))
                    Store (Arg0, HIID)
                    If (Local7)
                    {
                        Multiply (B1B2 (FCB0, FCB1), 0x0A, Local1)
                    }
                    Else
                    {
                        Store (B1B2 (FCB0, FCB1), Local1)
                    }

                    Store (Local1, Index (Arg1, 0x02))
                    Or (Arg0, 0x02, HIID)
                    If (Local7)
                    {
                        Multiply (B1B2 (DCB0, DCB1), 0x0A, Local0)
                    }
                    Else
                    {
                        Store (B1B2 (DCB0, DCB1), Local0)
                    }

                    Store (Local0, Index (Arg1, One))
                    Divide (Local1, 0x14, Local2, Index (Arg1, 0x05))
                    If (Local7)
                    {
                        Store (0xC8, Index (Arg1, 0x06))
                    }
                    ElseIf (B1B2 (DVB0, DVB1))
                    {
                        Divide (0x00030D40, B1B2 (DVB0, DVB1), Local2, Index (Arg1, 0x06))
                    }
                    Else
                    {
                        Store (Zero, Index (Arg1, 0x06))
                    }

                    Store (B1B2 (DVB0, DVB1), Index (Arg1, 0x04))
                    Store (B1B2 (SNB0, SNB1), Local0)
                    Name (SERN, Buffer (0x06)
                    {
                        &quot;     &quot;
                    })
                    Store (0x04, Local2)
                    While (Local0)
                    {
                        Divide (Local0, 0x0A, Local1, Local0)
                        Add (Local1, 0x30, Index (SERN, Local2))
                        Decrement (Local2)
                    }

                    Store (SERN, Index (Arg1, 0x0A))
                    Or (Arg0, 0x06, HIID)
                    Store (RECB (0xA0, 0x80), Index (Arg1, 0x09))
                    Or (Arg0, 0x04, HIID)
                    Name (BTYP, Buffer (0x05)
                    {
                         0x00, 0x00, 0x00, 0x00, 0x00                   
                    })
                    Store (B1B4 (CHB0, CHB1, CHB2, CHB3), BTYP)
                    Store (BTYP, Index (Arg1, 0x0B))
                    Or (Arg0, 0x05, HIID)
                    Store (RECB (0xA0, 0x80), Index (Arg1, 0x0C))
                }
                Else
                {
                    Store (0xFFFFFFFF, Index (Arg1, One))
                    Store (Zero, Index (Arg1, 0x05))
                    Store (Zero, Index (Arg1, 0x06))
                    Store (0xFFFFFFFF, Index (Arg1, 0x02))
                }

                Release (BATM)
                Return (Arg1)
            }
            Else
            {
                Return (XBIF (Arg0, Arg1, Arg2))
            }
        }

        Method (GBST, 4, NotSerialized)
        {
            If (_OSI (&quot;Darwin&quot;))
            {
                Acquire (BATM, 0xFFFF)
                If (And (Arg1, 0x20))
                {
                    Store (0x02, Local0)
                }
                ElseIf (And (Arg1, 0x40))
                {
                    Store (One, Local0)
                }
                Else
                {
                    Store (Zero, Local0)
                }

                If (And (Arg1, 0x07)){}
                Else
                {
                    Or (Local0, 0x04, Local0)
                }

                If (LEqual (And (Arg1, 0x07), 0x07))
                {
                    Store (0x04, Local0)
                    Store (Zero, Local1)
                    Store (Zero, Local2)
                    Store (Zero, Local3)
                }
                Else
                {
                    Store (Arg0, HIID)
                    Store (B1B2 (VOB0, VOB1), Local3)
                    If (Arg2)
                    {
                        Multiply (B1B2 (RCB0, RCB1), 0x0A, Local2)
                    }
                    Else
                    {
                        Store (B1B2 (RCB0, RCB1), Local2)
                    }

                    Store (B1B2 (ACB0, ACB1), Local1)
                    If (LGreaterEqual (Local1, 0x8000))
                    {
                        If (And (Local0, One))
                        {
                            Subtract (0x00010000, Local1, Local1)
                        }
                        Else
                        {
                            Store (Zero, Local1)
                        }
                    }
                    ElseIf (LNot (And (Local0, 0x02)))
                    {
                        Store (Zero, Local1)
                    }

                    If (Arg2)
                    {
                        Multiply (Local3, Local1, Local1)
                        Divide (Local1, 0x03E8, Local7, Local1)
                    }
                }

                Store (Local0, Index (Arg3, Zero))
                Store (Local1, Index (Arg3, One))
                Store (Local2, Index (Arg3, 0x02))
                Store (Local3, Index (Arg3, 0x03))
                Release (BATM)
                Return (Arg3)
            }
            Else
            {
                Return (XBST (Arg0, Arg1, Arg2, Arg3))
            }
        }
</code></pre>
<p>如上所示，即为最后的处理结果。</p>
<h1 id="32位以上字节的处理">32位以上字节的处理</h1>
<p>步骤基本相同，也是搜索所需修改字节对应对Method，然后找到对应路径，添加到SSDT中。<br>
<em><strong>32位以上的，不需要Field下的更改，只需要改Method，进行RECB和WECB的处理</strong></em></p>
<p>详细见DSDT教程中。</p>
<p>以下为完整处理结果（其实也在上文Method的GBIF，GBST中）（包含了全部）</p>
<pre><code class="language-swift">    Scope (\_SB.PCI0.LPC.EC)
    {
        Method (RE1B, 1, NotSerialized)
        {
            OperationRegion (ERM2, EmbeddedControl, Arg0, One)
            Field (ERM2, ByteAcc, NoLock, Preserve)
            {
                BYTE,   8
            }

            Return (BYTE)
        }

        Method (RECB, 2, Serialized)
        {
            ShiftRight (Add (Arg1, 0x07), 0x03, Arg1)
            Name (TEMP, Buffer (Arg1){})
            Add (Arg1, Arg0, Arg1)
            Store (Zero, Local0)
            While (LLess (Arg0, Arg1))
            {
                Store (RE1B (Arg0), Index (TEMP, Local0))
                Increment (Arg0)
                Increment (Local0)
            }

            Return (TEMP)
        }

        OperationRegion (ECOX, EmbeddedControl, Zero, 0x0100)
        Field (ECOX, ByteAcc, NoLock, Preserve)
        {
            Offset (0xA0), 
            RCB0,   8, 
            RCB1,   8, 
            FCB0,   8, 
            FCB1,   8, 
            Offset (0xA8), 
            ACB0,   8, 
            ACB1,   8, 
            VOB0,   8, 
            VOB1,   8
        }

        Field (ECOX, ByteAcc, NoLock, Preserve)
        {
            Offset (0xA0), 
            BMB0,   8, 
            BMB1,   8
        }

        Field (ECOX, ByteAcc, NoLock, Preserve)
        {
            Offset (0xA0), 
            DCB0,   8, 
            DCB1,   8, 
            DVB0,   8, 
            DVB1,   8, 
            Offset (0xAA), 
            SNB0,   8, 
            SNB1,   8
        }

        Field (ECOX, ByteAcc, NoLock, Preserve)
        {
            Offset (0xA0), 
            CHB0,   8, 
            CHB1,   8, 
            CHB2,   8, 
            CHB3,   8
        }

        Method (GBIF, 3, NotSerialized)
        {
            If (_OSI (&quot;Darwin&quot;))
            {
                Acquire (BATM, 0xFFFF)
                If (Arg2)
                {
                    Or (Arg0, One, HIID)
                    Store (B1B2 (BMB0, BMB1), Local7)
                    ShiftRight (Local7, 0x0F, Local7)
                    XOr (Local7, One, Index (Arg1, Zero))
                    Store (Arg0, HIID)
                    If (Local7)
                    {
                        Multiply (B1B2 (FCB0, FCB1), 0x0A, Local1)
                    }
                    Else
                    {
                        Store (B1B2 (FCB0, FCB1), Local1)
                    }

                    Store (Local1, Index (Arg1, 0x02))
                    Or (Arg0, 0x02, HIID)
                    If (Local7)
                    {
                        Multiply (B1B2 (DCB0, DCB1), 0x0A, Local0)
                    }
                    Else
                    {
                        Store (B1B2 (DCB0, DCB1), Local0)
                    }

                    Store (Local0, Index (Arg1, One))
                    Divide (Local1, 0x14, Local2, Index (Arg1, 0x05))
                    If (Local7)
                    {
                        Store (0xC8, Index (Arg1, 0x06))
                    }
                    ElseIf (B1B2 (DVB0, DVB1))
                    {
                        Divide (0x00030D40, B1B2 (DVB0, DVB1), Local2, Index (Arg1, 0x06))
                    }
                    Else
                    {
                        Store (Zero, Index (Arg1, 0x06))
                    }

                    Store (B1B2 (DVB0, DVB1), Index (Arg1, 0x04))
                    Store (B1B2 (SNB0, SNB1), Local0)
                    Name (SERN, Buffer (0x06)
                    {
                        &quot;     &quot;
                    })
                    Store (0x04, Local2)
                    While (Local0)
                    {
                        Divide (Local0, 0x0A, Local1, Local0)
                        Add (Local1, 0x30, Index (SERN, Local2))
                        Decrement (Local2)
                    }

                    Store (SERN, Index (Arg1, 0x0A))
                    Or (Arg0, 0x06, HIID)
                    Store (RECB (0xA0, 0x80), Index (Arg1, 0x09))
                    Or (Arg0, 0x04, HIID)
                    Name (BTYP, Buffer (0x05)
                    {
                         0x00, 0x00, 0x00, 0x00, 0x00                   
                    })
                    Store (B1B4 (CHB0, CHB1, CHB2, CHB3), BTYP)
                    Store (BTYP, Index (Arg1, 0x0B))
                    Or (Arg0, 0x05, HIID)
                    Store (RECB (0xA0, 0x80), Index (Arg1, 0x0C))
                }
                Else
                {
                    Store (0xFFFFFFFF, Index (Arg1, One))
                    Store (Zero, Index (Arg1, 0x05))
                    Store (Zero, Index (Arg1, 0x06))
                    Store (0xFFFFFFFF, Index (Arg1, 0x02))
                }

                Release (BATM)
                Return (Arg1)
            }
            Else
            {
                Return (XBIF (Arg0, Arg1, Arg2))
            }
        }

        Method (GBST, 4, NotSerialized)
        {
            If (_OSI (&quot;Darwin&quot;))
            {
                Acquire (BATM, 0xFFFF)
                If (And (Arg1, 0x20))
                {
                    Store (0x02, Local0)
                }
                ElseIf (And (Arg1, 0x40))
                {
                    Store (One, Local0)
                }
                Else
                {
                    Store (Zero, Local0)
                }

                If (And (Arg1, 0x07)){}
                Else
                {
                    Or (Local0, 0x04, Local0)
                }

                If (LEqual (And (Arg1, 0x07), 0x07))
                {
                    Store (0x04, Local0)
                    Store (Zero, Local1)
                    Store (Zero, Local2)
                    Store (Zero, Local3)
                }
                Else
                {
                    Store (Arg0, HIID)
                    Store (B1B2 (VOB0, VOB1), Local3)
                    If (Arg2)
                    {
                        Multiply (B1B2 (RCB0, RCB1), 0x0A, Local2)
                    }
                    Else
                    {
                        Store (B1B2 (RCB0, RCB1), Local2)
                    }

                    Store (B1B2 (ACB0, ACB1), Local1)
                    If (LGreaterEqual (Local1, 0x8000))
                    {
                        If (And (Local0, One))
                        {
                            Subtract (0x00010000, Local1, Local1)
                        }
                        Else
                        {
                            Store (Zero, Local1)
                        }
                    }
                    ElseIf (LNot (And (Local0, 0x02)))
                    {
                        Store (Zero, Local1)
                    }

                    If (Arg2)
                    {
                        Multiply (Local3, Local1, Local1)
                        Divide (Local1, 0x03E8, Local7, Local1)
                    }
                }

                Store (Local0, Index (Arg3, Zero))
                Store (Local1, Index (Arg3, One))
                Store (Local2, Index (Arg3, 0x02))
                Store (Local3, Index (Arg3, 0x03))
                Release (BATM)
                Return (Arg3)
            }
            Else
            {
                Return (XBST (Arg0, Arg1, Arg2, Arg3))
            }
        }
    }
</code></pre>
<p>可以对照给出的X260的热补丁看看</p>
<h1 id="排错补充引用声明">排错，补充引用声明</h1>
<p>完成这些步骤后，点击编译会发现错误<br>
<img src="http://fp1.fghrsh.net/2020/04/09/63be505b7792df708a4d5b51ca8892a4.png" alt="63be505b7792df708a4d5b51ca8892a4.png" loading="lazy"></p>
<p>这些都是因为没有被定义，因此我们需要进行引用，来排除这些错误。<br>
以BATM为例，在DSDT中进行搜索，找到它被定义的路径和类型，写成External</p>
<p><code>External (_SB.PCI0.LPC.EC_BATM, MutexObj)</code></p>
<p>前者为路径，后者为类型</p>
<p>更多详见如下：</p>
<p>以下摘自iStar的博客：<br>
Device：原始 ACPI 定义示例</p>
<pre><code class="language-swift">Scope (_SB.PCI0.LPCB)
{
    Device (H_EC)
    {
</code></pre>
<p>补丁中添加的代码示例</p>
<pre><code class="language-swift">External (_SB_.PCI0.LPCB.H_EC, DeviceObj)
</code></pre>
<p>Method：原始 ACPI 定义示例</p>
<pre><code class="language-swift">Method (_STA, 0, NotSerialized)  /* _STA: Status */
</code></pre>
<p>补丁中添加的代码示例</p>
<pre><code class="language-swift">External (_SB_.BAT0._STA, MethodObj)
</code></pre>
<p>Mutex：原始 ACPI 定义示例</p>
<pre><code class="language-swift">Mutex (BATM, 0x07)
</code></pre>
<p>补丁中添加的代码示例</p>
<pre><code class="language-swift">External (_SB_.PCI0.LPCB.H_EC.BATM, MutexObj)
</code></pre>
<p>FieldUnit：原始 ACPI 定义示例</p>
<pre><code class="language-swift">Field(...)
{
...
BCNT,   8,
...
}
</code></pre>
<p>补丁中添加的代码示例</p>
<pre><code class="language-swift">External (_SB_.PCI0.LPCB.H_EC.BCNT, FieldUnitObj)
</code></pre>
<p>Integer：原始 ACPI 定义示例</p>
<pre><code class="language-swift">Name (ECA2, Zero)
</code></pre>
<p>补丁中添加的代码示例</p>
<pre><code class="language-swift">External (_SB_.PCI0.LPCB.H_EC.ECA2, IntObj)
</code></pre>
<p>Package：原始 ACPI 定义示例</p>
<pre><code class="language-swift">Name (PBIF, Package (0x0D)
{
    One,
    0xFFFFFFFF,
    0xFFFFFFFF,
    One,
    0xFFFFFFFF,
    0xFA,
    0x96,
    0x0A,
    0x19,
    &quot;BAT0&quot;,
    &quot; &quot;,
    &quot; &quot;,
    &quot; &quot;
})
</code></pre>
<p>补丁中添加的代码示例</p>
<pre><code class="language-swift">External (_SB_.BAT0.PBIF, PkgObj)
</code></pre>
<h1 id="添加if判断语句">添加if判断语句</h1>
<p>为了让自己修改的Method不会影响Windows系统，我们需要添加if判断语句，明确它的内容作用在哪个系统。</p>
<p>如，在GBIF这个Method的第一个括号下加入<strong>If (_OSI (&quot;Darwin&quot;))</strong></p>
<pre><code class="language-swift">        Method (GBIF, 3, NotSerialized)
        {
            If (_OSI (&quot;Darwin&quot;))
            {
                Acquire (BATM, 0xFFFF)
                If (Arg2)
       .....
</code></pre>
<p>然后，我们去到这个Method的尾部，看看这个Method，最后有没有返回（Return）<br>
很显然这个GBIF有的，就是<strong>Return (Arg1)</strong><br>
对于有返回语句的，我们需要在Else下加上Return，没有则不需要。</p>
<p>Else部分自己加在Method末尾。</p>
<p>最终结果如下：</p>
<pre><code class="language-swift">        Method (GBIF, 3, NotSerialized)
        {
            If (_OSI (&quot;Darwin&quot;))
            {
                Acquire (BATM, 0xFFFF)
                If (Arg2)
                {
                    Or (Arg0, One, HIID)
                    Store (B1B2 (BMB0, BMB1), Local7)
                    ShiftRight (Local7, 0x0F, Local7)
                    XOr (Local7, One, Index (Arg1, Zero))
                    Store (Arg0, HIID)
                    If (Local7)
                    {
                        Multiply (B1B2 (FCB0, FCB1), 0x0A, Local1)
                    }
                    Else
                    {
                        Store (B1B2 (FCB0, FCB1), Local1)
                    }

                    Store (Local1, Index (Arg1, 0x02))
                    Or (Arg0, 0x02, HIID)
                    If (Local7)
                    {
                        Multiply (B1B2 (DCB0, DCB1), 0x0A, Local0)
                    }
                    Else
                    {
                        Store (B1B2 (DCB0, DCB1), Local0)
                    }

                    Store (Local0, Index (Arg1, One))
                    Divide (Local1, 0x14, Local2, Index (Arg1, 0x05))
                    If (Local7)
                    {
                        Store (0xC8, Index (Arg1, 0x06))
                    }
                    ElseIf (B1B2 (DVB0, DVB1))
                    {
                        Divide (0x00030D40, B1B2 (DVB0, DVB1), Local2, Index (Arg1, 0x06))
                    }
                    Else
                    {
                        Store (Zero, Index (Arg1, 0x06))
                    }

                    Store (B1B2 (DVB0, DVB1), Index (Arg1, 0x04))
                    Store (B1B2 (SNB0, SNB1), Local0)
                    Name (SERN, Buffer (0x06)
                    {
                        &quot;     &quot;
                    })
                    Store (0x04, Local2)
                    While (Local0)
                    {
                        Divide (Local0, 0x0A, Local1, Local0)
                        Add (Local1, 0x30, Index (SERN, Local2))
                        Decrement (Local2)
                    }

                    Store (SERN, Index (Arg1, 0x0A))
                    Or (Arg0, 0x06, HIID)
                    Store (RECB (0xA0, 0x80), Index (Arg1, 0x09))
                    Or (Arg0, 0x04, HIID)
                    Name (BTYP, Buffer (0x05)
                    {
                         0x00, 0x00, 0x00, 0x00, 0x00                   
                    })
                    Store (B1B4 (CHB0, CHB1, CHB2, CHB3), BTYP)
                    Store (BTYP, Index (Arg1, 0x0B))
                    Or (Arg0, 0x05, HIID)
                    Store (RECB (0xA0, 0x80), Index (Arg1, 0x0C))
                }
                Else
                {
                    Store (0xFFFFFFFF, Index (Arg1, One))
                    Store (Zero, Index (Arg1, 0x05))
                    Store (Zero, Index (Arg1, 0x06))
                    Store (0xFFFFFFFF, Index (Arg1, 0x02))
                }

                Release (BATM)
                Return (Arg1)
            }
            Else
            {
                Return (XBIF (Arg0, Arg1, Arg2))
            }
        }
</code></pre>
<p>我们发现，我将GBIF在Else中重命名为了XBIF，这需要与后面config里添加重命名对应。<br>
那么，你们可能会有疑问，这个Arg0这些是这么来的？<br>
这个需要观察：</p>
<pre><code class="language-swift">Method (GBIF, 3, NotSerialized)
</code></pre>
<p>就是中间这个数字得来的，3的话就是在XBIF后面的括号里填写，Arg0， Arg1， Arg2。<br>
是多少，你就从Arg0开始往后一个个按顺序加。0就不填，留空。</p>
<p>添加完了这些后，你再编译，发现报错了，然后一样，补充引用声明。<br>
如，</p>
<pre><code class="language-swift">External (_SB.PCI0.LPC.EC.XBIF, MethodObj)
</code></pre>
<p>这样就可以了。</p>
<h1 id="重命名与mutex检查">重命名与Mutex检查</h1>
<p>最后，我们来进行重命名和Mutex检查<br>
比如GBIF，我们来重命名为XBIF，这样就不会与ACPI中的GBIF冲突了<br>
规则如下：<br>
<code>Comment：BAT GBIF to XBIF</code><br>
利用Hackintool，将GBIF转换为16进制为：47424946<br>
我们再补上两位，这两位就需要看Method了</p>
<pre><code class="language-swift">Method (GBIF, 3, NotSerialized)
</code></pre>
<p>NotSerialized代表0，Serialized代表8<br>
我们将其相加，中间的数字+N或S<br>
GBIF就是：3+0=3，3转换为16进制就是3<br>
那么最后的两位就是03</p>
<p>XBIF的16进制为：58424946</p>
<p>完整的如下：<br>
<code>Comment：BAT GBIF to XBIF</code><br>
<code>Find：47424946 03</code><br>
<code>Replace：58424946 03</code></p>
<p>GBST的就是：<br>
<code>Method (GBST, 4, NotSerialized)</code></p>
<p><code>Comment：BAT GBST to XBST</code><br>
<code>Find：47425354 04</code><br>
<code>Replace：58425354 04</code></p>
<p>把这些重命名加到Config里。</p>
<p>你需要检查Mutex，确保他们全部为0 在当前使用的DSDT文件里搜索Mutex，看出现的几个变量是否为0，目前所知道的绝大多数机器的ACPI Mutex都是默认置0的，但是对于一些联想机器，它们往往有几个Mutex初始值并不是0，这里我们利用ACPI二进制更名的方法实现置0</p>
<p>以Mutex (BATM, 0x07)为例，先转换BATM为十六进制代码，得到 42 41 54 4D</p>
<p>在前后加上完整定义的十六进制代码，01代表Mutex，07则代表默认值，最终得到 01 42 41 54 4D 07</p>
<p>我们的目的是使Mutex对象置0，所以config的更名应填</p>
<p><code>Comment Set Mutex BATM, 0x07 to 0x0</code><br>
<code>Find 01 42 41 54 4D 07</code><br>
<code>Repalce 01 42 41 54 4D 00</code><br>
其它Mutex对象按照同样的方法处理即可</p>
<p>这样下来你的电池热补丁就基本制作完毕了，对于双电池系统的电池（实际只有一块电池的），我们需要禁用其中一个。</p>
<h1 id="双电池系统屏蔽其中一个">双电池系统，屏蔽其中一个</h1>
<p>比如，你的DSDT中有BAT0或BAT1两个电池设备，但你实际只在用其中一个。那么，你先看看另一个是否开启，如果另一个也是开启的，你需要屏蔽它。</p>
<p>参考我给的<strong>SSDT-BAT0-Disable-X260.aml</strong></p>
<figure data-type="image" tabindex="3"><img src="http://fp1.fghrsh.net/2020/04/09/623eacaa93ddd83f4c6e702f3386d33f.png" alt="623eacaa93ddd83f4c6e702f3386d33f.png" loading="lazy"></figure>
<p>将DefinitionBlock框出来的位置，改成自己的，同时修改External和Scope为自己所要屏蔽的电池设备的路径。</p>
<p>然后保存即可。</p>
<p>然后我们要对所屏蔽电池设备下的_STA进行更名：</p>
<p><strong>CLOVER</strong>：处理比较简单，将所需屏蔽的电池设备，转换为16进制，比如BAT1（42415430）<br>
<code>Comment：BAT _STA to XSTA in BAT1</code><br>
<code>Find：5F535441</code><br>
<code>Replace：58535441</code><br>
<code>TgtBridge：42415431</code></p>
<p><strong>OC</strong>：OpenCore因为没有TgtBridge，因此处理比较麻烦<br>
1.选择使用skip，count：Skip为跳过，就看你所要更改的_STA上有几个一样的_STA就跳过几个，count是替换次数，填1次即可<br>
<code>Comment：BAT _STA to XSTA in BAT1</code><br>
<code>Find：5F535441</code><br>
<code>Replace：58535441</code><br>
<code>Skip:（填跳过的次数）</code><br>
<code>Count：1</code></p>
<p>到这里，你已经做好一个电池热补丁和屏蔽补丁了，然后再加上ACPIBatteryManager.kext或者SMCBatteryManager.kext，不出问题，你就可以看到你可爱的电池图标了！<br>
<img src="http://fp1.fghrsh.net/2020/04/09/62971b7a3ea5acec10213463913ea58f.png" alt="62971b7a3ea5acec10213463913ea58f.png" loading="lazy"><br>
<img src="http://fp1.fghrsh.net/2020/04/09/e6f18d2331d465d9513490e29845e1db.png" alt="e6f18d2331d465d9513490e29845e1db.png" loading="lazy"></p>

                </div>
            </article>
        </div>

        
            <div class="next-post">
                <div class="next gt-c-content-color-first">下一篇</div>
                <a href="https://gzxiaobai.github.io/post/ru-he-jian-dan-de-bian-yi-opencore/" class="post-title gt-a-link">
                    如何简单的编译OpenCore
                </a>
            </div>
        

        
		
		
			<script src='https://unpkg.com/valine/dist/Valine.min.js'></script>

<style>
	div#vcomments{
		width:100%;
		max-width: 1000px;
		padding: 2.5%
	}
</style>


	<div id="vcomments"></div>

<script>
	new Valine({
		el: '#vcomments',
		appId: 'hcgePHaJOceH3R36dS7FxVSJ-gzGzoHsz',
		appKey: '7RPXugMe92rdtnjtiCD1P2Lm',
		avatar: '',
		pageSize: 5,
		recordIp: true,
		placeholder: 'Just Go Go'
	});
</script>
		

        <div class="site-footer gt-c-content-color-first">
    <div class="slogan gt-c-content-color-first">这是一个正常的人（确信）</div>
    <div class="social-container">
        
            
                <a href="https://github.com/GZXiaoBai" target="_blank">
                    <i class="fab fa-github gt-c-content-color-first"></i>
                </a>
            
        
            
        
            
        
            
        
            
        
            
        
    </div>
    <div class="footer-info">
        Powered by <a href="https://github.com/getgridea/gridea" target="_blank">Gridea</a>
    </div>
    <div>
        Theme by <a href="https://imhanjie.com/" target="_blank">imhanjie</a>, Powered by <a
                href="https://github.com/getgridea/gridea" target="_blank">Gridea | <a href="https://gzxiaobai.github.io/atom.xml" target="_blank">RSS</a></a>
    </div>
</div>

<script>
    hljs.initHighlightingOnLoad()
</script>

    </div>
</div>
</body>
</html>
